/************************************************************
 * $Id : CmdLeave.cpp   2011/08/01
 *
 *       swhors@naver.com
 ************************************************************/

#include "config.h"

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

using namespace std;

#include "constant.h"
#include "ast_peg.h"
#include "ast_db.h"
#include "CmdBase.h"
#include "CmdLeave.h"
#include "ast_util.h"
#include "ast_event.h"
#include "SkyConfUtil.h"

extern int gIsConnected2DB;

extern int sendCommand( char *aFmt, ... );

CCmdLeave::CCmdLeave()
{
    init();
}

CCmdLeave::~CCmdLeave()
{
    init();
}

void CCmdLeave::release()
{
    super::release();
}

void CCmdLeave::init()
{
    super::init();

    memset( mConferenceName , 0, 32 );
    memset( mUniqueId,        0, 32 );
    memset( mFlags,           0, 12 );
    memset( mCallerId,        0, 32 );
    memset( mCallerIdName,    0, 32 );

    mMember   = 0;
    mDuration = 0;
    mCount    = 0;
}

void *CCmdLeave::parse(char * aCommand )
{
    char * sStart      = NULL;
    char * sMsgStartPtr = NULL;
    char   sBuff[32]    = {0,};

    sMsgStartPtr = aCommand;
    super::parse( sMsgStartPtr );

    sMsgStartPtr = aCommand;
    if( conferencename_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( mConferenceName, 0, 32 );
        memcpy( mConferenceName,
                sStart + 16,
                ( sMsgStartPtr - sStart - 18 ) );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( uniqueid_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( mUniqueId, 0, 32 );
        memcpy( mUniqueId,
                sStart + 10,
                ( sMsgStartPtr - sStart - 12 ) );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( member_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( sBuff, 0, 32 );
        memcpy( sBuff,
                sStart + 8,
                ( sMsgStartPtr - sStart - 10 ) );
        mMember = atoi( (char *) &sBuff );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( flags_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( mFlags, 0, 12 );
        memcpy( mFlags,
                sStart + 7,
                ( sMsgStartPtr - sStart - 9 ) );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( callerid_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( mCallerId, 0, 32 );
        memcpy( mCallerId,
                sStart + 10,
                ( sMsgStartPtr - sStart - 12 ) );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( calleridname_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( mCallerIdName, 0, 32 );
        memcpy( mCallerIdName,
                sStart + 14,
                ( sMsgStartPtr - sStart - 16 ) );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( duration_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( sBuff, 0, 32 );
        memcpy( sBuff,
                sStart + 10,
                ( sMsgStartPtr - sStart - 12 ) );
        mDuration= atoi( (char *) &sBuff );
    }
    else
    {
        /* do nothing */
    }

    sMsgStartPtr = aCommand;
    if( count_f::Matches( sMsgStartPtr, sStart ) )
    {
        memset( sBuff, 0, 32 );
        memcpy( sBuff,
                sStart + 7,
                ( sMsgStartPtr - sStart - 9 ) );
        mCount = atoi( (char *) &sBuff );
    }
    else
    {
        /* do nothing */
    }

    return this;
}

CCmdLeave &CCmdLeave::operator = ( const CCmdLeave &aOther )
{
    sprintf( mPrivilege,      "%s", aOther.mPrivilege );
    sprintf( mConferenceName, "%s", aOther.mConferenceName );
    sprintf( mUniqueId,       "%s", aOther.mUniqueId );
    sprintf( mFlags,          "%s", aOther.mFlags );
    sprintf( mChannel,        "%s", aOther.mChannel );
    sprintf( mCallerId,       "%s", aOther.mCallerId );
    sprintf( mCallerIdName,   "%s", aOther.mCallerIdName );

    mMember   = aOther.mMember;
    mDuration = aOther.mDuration;
    mCount    = aOther.mCount;
    return *this;
}

int CCmdLeave::operator < ( const CCmdLeave &aOther )
{
    int sRetVal = 0;

    sRetVal = strcmp( mPrivilege, aOther.mPrivilege);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mConferenceName,
                      aOther.mConferenceName);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mUniqueId,
                      aOther.mUniqueId);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    if( mMember < aOther.mMember )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mFlags,
                      aOther.mFlags);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mChannel,
                      aOther.mChannel);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mCallerId,
                      aOther.mCallerId);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    sRetVal = strcmp( mCallerIdName,
                      aOther.mCallerIdName);
    if( sRetVal < 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    if( mDuration < aOther.mDuration )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    if( mCount < aOther.mCount )
    {
        /* do nothing */
    }
    else
    {
        goto notless;
    }

    return 1;

notless:

    return 0;
}

int CCmdLeave::operator > ( const CCmdLeave &aOther )
{
    int sRetVal = 0;

    sRetVal =  strcmp( mPrivilege,
                       aOther.mPrivilege);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mConferenceName,
                       aOther.mConferenceName);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mUniqueId,
                       aOther.mUniqueId);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    if( mMember > aOther.mMember )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mFlags, aOther.mFlags);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mChannel,
                       aOther.mChannel);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mCallerId,
                       aOther.mCallerId);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    sRetVal =  strcmp( mCallerIdName,
                       aOther.mCallerIdName);
    if( sRetVal > 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    if( mDuration > aOther.mDuration )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    if( mCount > aOther.mCount )
    {
        /* do nothing */
    }
    else
    {
        goto notmore;
    }

    return 1;

notmore:

    return 0;
}

int CCmdLeave::operator == (const CCmdLeave &aOther)
{
    int sRetVal = 0;

    sRetVal = strcmp( mPrivilege,
                      aOther.mPrivilege );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mConferenceName,
                      aOther.mConferenceName );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mUniqueId,
                      aOther.mUniqueId );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    if( mMember == aOther.mMember )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mFlags,
                      aOther.mFlags );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mChannel,
                      aOther.mChannel );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mCallerId,
                      aOther.mCallerId );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    sRetVal = strcmp( mCallerIdName,
                      aOther.mCallerIdName );
    if( sRetVal == 0 )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    if( mDuration == aOther.mDuration )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    if( mCount == aOther.mCount )
    {
        /* do nothing */
    }
    else
    {
        goto notequal;
    }

    return 1;

notequal:

    return 0;
}

int CCmdLeave::event()
{
    char sOutChanName[USERNAME_MAX_LEN];
    char sChannelList[10][64];
    int  sRetCode = 0;
    int  sBufLen  = 10;
    int  sCnt     = 0;

    char sFileName[256]; // filename buffer for removing

    memset( sOutChanName, 0, sizeof(char) * USERNAME_MAX_LEN );

    GetConfOutChanName( sOutChanName, USERNAME_MAX_LEN );

    if( gIsConnected2DB )
    {

        (void)online_sql_set_lasttalk(
                       mConferenceName,
                       sOutChanName );

        if( online_sql_del_conf( mConferenceName,
                                 mChannel,
                                 mMember ) )
        {
            // 1) cdr

            // 2) flags process
            if( strstr(mFlags, "i") )
            {
                if( mCount > 0 )
                {
                    if( mCount > 1 )
                    {
                        online_sql_get_channellist(
                            mConferenceName,
                            sChannelList,
                            &sBufLen,
                            1 );
                        if( sBufLen > 0 )
                        {
                            for( sCnt = 0 ;sCnt < sBufLen; sCnt++)
                            {
                                sRetCode = sendCommand( AST_CMD_PLAY_SND_1, 
                                                        sChannelList[sCnt],
                                                        mConferenceName,
                                                        mUniqueId );
                            }
                        }
                        else
                        {
                            log_message( AST_ERR_CONF_LEAVE_1, 'i' );
                        }
                    }
                }
                else
                {
                    // no more users are in this conference
                    // remove announce files
                    sprintf( sFileName,
                        "/tmp/%s/%s",
                        mConferenceName,
                        mUniqueId);
                    remove( sFileName );

                    sprintf( sFileName,
                        "/tmp/%s",
                        mConferenceName );
                    remove( sFileName );
                }
            }
            if( !strstr(mFlags, "q") )
            {
                online_sql_get_channellist(
                          mConferenceName,
                          sChannelList,
                          &sBufLen,
                          1 );
                if( sBufLen > 0 )
                {
                    for( sCnt = 0 ; sCnt < sBufLen ; sCnt++)
                    {
                        sRetCode = sendCommand( AST_CMD_PLAY_SND_2, 
                                                sChannelList[sCnt]);
                    }
                }
                else
                {
                    log_message( AST_ERR_CONF_LEAVE_1, 'q' );
                }
            }

            if( mCount == 0 )
            {
                online_sql_get_channellist(
                    mConferenceName,
                    sChannelList,
                    &sBufLen,
                    1 );
                if( sBufLen > 0 )
                {
                    for( sCnt = 0 ; sCnt < sBufLen ; sCnt++)
                    {
                        sRetCode = sendCommand(
                                       AST_CMD_PLAY_SND_3, 
                                       sChannelList[sCnt] );
                    }
                }
                else
                {
                    log_message( AST_ERR_CONF_LEAVE_2 );
                }
            }
            if( strstr( mFlags, "h" ) )
            {
                if( !strstr( mFlags, "w" ) )
                {
                    online_sql_get_channellist(
                        mConferenceName,
                        sChannelList,
                        &sBufLen,
                        1 );
                    if( sBufLen > 0 )
                    {
                        for( sCnt = 0 ; sCnt< sBufLen ; sCnt++ )
                        {
                            sRetCode = sendCommand(
                                         AST_CMD_START_CONF_1, 
                                         sChannelList[sCnt] );
                        }
                    }
                    else
                    {
                        log_message(AST_ERR_CONF_LEAVE_1, 'w' ); 
                    }
                }
            }
            goto event_success;
        }
    }

    goto event_fail;

    event_success:
    return sRetCode;

    event_fail:
    return 0;
}
